#include "RenderTexture2D.h"

#include "Render/Texture/Texture2DPixels.h"

CRenderTexture2D::CRenderTexture2D()
{
    WriteInTexture = new CTexture2DPixels();
}

void CRenderTexture2D::SyncToRenderThread(const TVector<uint8_t> &InData, const uint32_t InWidth, const uint32_t InHeight, const uint32_t InPitch, ETextureFormat InFormat)
{
    assert(InWidth>0 && InHeight>0 && InPitch>0 && InData.Num()>0);
    std::lock_guard<std::mutex> LockGuard(WriteInTexture->Mutex);
    WriteInTexture->Data = InData;
    WriteInTexture->Width = InWidth;
    WriteInTexture->Height = InHeight;
    WriteInTexture->Pitch = InPitch;
    WriteInTexture->Format = InFormat;
    WriteInTexture->bDirty = true;
}

uint32_t CRenderTexture2D::GetWidth() const
{
    std::lock_guard<std::mutex> LockGuard(WriteInTexture->Mutex);
    return WriteInTexture->Width;
}

uint32_t CRenderTexture2D::GetHeight() const
{
    std::lock_guard<std::mutex> LockGuard(WriteInTexture->Mutex);
    return WriteInTexture->Height;
}

// void CRenderTexture2D::MakeSureNotDirty()
// {

//     if(!VulkanTexture)
//     {
//         VulkanTexture = std::make_shared<CVulkanTexture2D>();
//     }

//     ImageDataMutex.lock();
//     if(!bDirty)
//     {
//         ImageDataMutex.unlock();
//         return;
//     }
//     bDirty=false;
    
//     vk::Format Format = ToVulkanTextureFormat(WriteInFormat);
//     assert(Format != vk::Format::eUndefined);

//     VulkanTexture->Image.SetImageParams(WriteInWidth, WriteInHeight, Format);
//     VulkanTexture->Image.WriteData(WriteInData.data(), WriteInData.Num(), WriteInPitch);

//     WriteInData.Clear();

//     vk::ImageViewCreateInfo ImageViewCreateInfo=vk::ImageViewCreateInfo()
//         .setImage(VulkanTexture->Image.GetImage())
//         .setViewType(vk::ImageViewType::e2D)
//         .setFormat(Format)
//         .setSubresourceRange(vk::ImageSubresourceRange()
//             .setAspectMask(vk::ImageAspectFlagBits::eColor)
//             .setBaseMipLevel(0)
//             .setLevelCount(1)
//             .setBaseArrayLayer(0)
//             .setLayerCount(1));
//     VulkanTexture->ImageView=CVulkanContext::Get()->GetDevice().createImageView(ImageViewCreateInfo);
//     VulkanTexture->Width=WriteInWidth;
//     VulkanTexture->Height=WriteInHeight;
//     ImageDataMutex.unlock();

//     //convert image layout
//     vk::CommandBuffer ConvertImageLayoutCommandBuffer=CVulkanContext::Get()->GetConvertImageLayoutCommandBuffer();

//     vk::CommandBufferBeginInfo CommandBufferBeginInfo=vk::CommandBufferBeginInfo()
//         .setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);

//     ConvertImageLayoutCommandBuffer.begin(CommandBufferBeginInfo);

//     vk::ImageMemoryBarrier ImageMemoryBarrier=vk::ImageMemoryBarrier()
//         .setSrcAccessMask(vk::AccessFlagBits::eHostWrite)
//         .setDstAccessMask(vk::AccessFlagBits::eShaderRead)
//         .setOldLayout(vk::ImageLayout::ePreinitialized)
//         .setNewLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
//         .setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED)
//         .setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED)
//         .setImage(VulkanTexture->Image.GetImage())
//         .setSubresourceRange(vk::ImageSubresourceRange()
//             .setAspectMask(vk::ImageAspectFlagBits::eColor)
//             .setBaseMipLevel(0)
//             .setLevelCount(1)
//             .setBaseArrayLayer(0)
//             .setLayerCount(1));

//     ConvertImageLayoutCommandBuffer.pipelineBarrier(
//         vk::PipelineStageFlagBits::eHost
//         , vk::PipelineStageFlagBits::eFragmentShader
//         , vk::DependencyFlags()
//         , nullptr
//         , nullptr
//         , ImageMemoryBarrier);

    
//     ConvertImageLayoutCommandBuffer.end();

//     vk::SubmitInfo SubmitInfo=vk::SubmitInfo()
//         .setCommandBufferCount(1)
//         .setPCommandBuffers(&ConvertImageLayoutCommandBuffer);

//     CVulkanContext::Get()->GetGraphicQueue().submit(SubmitInfo
//         , CVulkanContext::Get()->GetConvertImageLayoutFence());

//     //wait for convert image layout
    

//     CVulkanContext::Get()->GetDevice().waitForFences(
//          {CVulkanContext::Get()->GetConvertImageLayoutFence()}
//         , VK_TRUE
//         , std::numeric_limits<uint64_t>::max());

//     CVulkanContext::Get()->GetDevice().resetFences(
//         {CVulkanContext::Get()->GetConvertImageLayoutFence()});

// }
